%FORMATFIG is used to modify figure formatting before exportation. It is
%based on exportfig (Ben Hinkle @MathWorks) but only some features of
%exportfig have been kept. Essentially, all the aspects of figure boundings
%and figure exportation have been removed. It has been found that using an
%eps export and then a file conversion is far more reliable to obtain a
%tight figure bounding. Many features have been added, including upgrades
%related to Matlab 7.x.
%
%CALL:
%
%   OPT_STRUCT = FORMATFIG( ...
%          FIG_HANDLE, [ OPT_STRUCT, ] [ 'PARAM_NAME', PARAM_VALUE, ] ... )
%
%   OPT_STRUCT: structure with fields .PARAM_NAME and values .PARAM_VALUE
%
%   NB: - for parameters present both in structure and list, the
%         values of the list will be used.
%       - the only required input is the figure handle FIG_HANDLE.
%       - if no parameters are given, OPT_STRUCT with default values is
%         returned.
%
%PARAMETERS
%
% FIGURE SIZE
%
%   width
%           Figure width in figure's PaperUnits. Positive scalar. Unchanged
%           or scaled: [] (default).
%
%   height
%           Figure width in figure's PaperUnits. Positive scalar. Unchanged
%           or scaled: [] (default).
%
%   refobj
%           Axes handle or string evaluating to an axes handle. If given,
%           'width' and 'height' are relative to the given axes. Default:
%           [].
%
%       Remark on width, height and refobj: 
%       Specifying only one dimension sets the other dimension so that the
%       new figure aspect ratio is the same as the figure's or reference
%       axes' current aspect ratio. If neither dimension is specified the
%       size defaults to the width and height from the screen figure's or
%       reference axes' size. 'PaperPositionMode' property is set to
%       'auto', so that the figure is displayed in real size (printed and
%       screen versions match).
%
%   activeposition
%           Conserved axes position during figure and/or font resizing:
%           'outerposition' (default), 'position' or [] (no change).
%           General guidelines:
%           - Use 'outerposition' to let Matlab adjust axes dimensions
%             automatically. Robust, but axes alignment and aspect ratio
%             will be lost.
%           - Use 'position' to maintain axes alignment (multiple subplots
%             or superposed axes). Might lead to label overlap if labels
%             are present between axes. Use 'adaptaxes' to correct label
%             clipping by figure frame.
%           NB: only for 7.x versions.
%
%   paperunits
%           Figure's PaperUnits property. Default: 'centimeters'. If empty
%           ([]), the PaperUnits property of the figure is not changed.
%                      
% AXES LOCKING
%
%   lockaxes
%           True / False (default) to lock all axes limits and ticks while
%           resizing.
%
%   locklimits
%           True / False (default): same as lockaxes but applied only for
%           limits mode.
%
%   lockticks
%           True / False (default): same as 'lockaxes' but applied only for
%           tick mode. Mostly useful when resizing fonts of LOG axis.
%
% RESIZING CORRECTIONS
%
%       Remark:
%       When resizing or increasing font size, a number of problems might
%       occur: clipping of axes labels, misalignment of axes, label
%       overlapping, non optimal legend positionning and so on. The
%       parameters given here allow a certain control on these problems.
%
%   adaptaxes
%           True / False (default) to adapt axes size and position to the
%           new font or figure sizes. This option can be used to avoid
%           label overlapping or cropping. The 6.x and 7.x versions are
%           different.
%
%       6.x version:   
%           Titles are not dealt with specially and may cause problems. Use
%           'rmtitle' to remove them. The power of 10 label should be dealt
%           with nicely. This option works if several plots are present on
%           a given figure, but it DOES NOT work with:
%               - 3D plots
%               - superposed axes
%
%       7.x versions:
%           If 'activeposition' is set to 'outerposition', Matlab should do
%           the job correctly, so that this option is mostly useful for
%           'position' mode. In any case, using this option will result in
%           testing that all the axes Position+TightInset are included in
%           the figure frame. If not, the figure margin will be increased.
%           This option has no controlled effect on the space between
%           subplots for 7.x versions.
%
%           Linked to: 'marginfactor', 'tight' and 'matchcolorbars'.
%
%   tight
%           To obtain the smallest possible figure margins (at least
%           in 'position' mode). 'tight' can be one of:
%
%           'x'     
%                   Keep figure dimension along x, adapt y to conserve
%                   axes proportion (at least in 'position' mode)
%           'y'     
%                   Keep figure dimension along y, adapt x to conserve
%                   axes proportion (at least in 'position' mode)
%           'xy'    
%                   Keep figure dimension along both x and y
%           []      
%                   Not tight (default).
%           
%           Remarks:
%           - 'tight' is applied after figure resizing so that the
%             dimensions that are kept are the dimensions given in 'width'
%             and/or 'height'.
%           - 'tight' is useful to control the exported figure width while
%             maintaining small margins (i.e. in combination with the
%             option 'eps_loose' of FIG2PUBLIC).
%           - In 'outerposition' mode, the margins will be tighter (but not 
%             the tightest) and the scaling will be approximatively
%             conserved. This is due to an impredictable behaviour of the
%             resizing function in this mode.
%           - 'tight' is less or not efficient in a number of cases:
%             3D plots, axes with equal and tight options activated, axes
%             with outsided legends.
%           - Linked to: 'adaptaxes' and 'marginfactor'.
%           - Only for 7.x versions.
%
%   marginfactor
%           A positive scalar (default 1) or a 4-column vector. Depending
%           on the size of 'marginfactor', the behaviour is different:
%           
%           Scalar:
%                   Used as a multiplication factor of the margin
%                   corrections determined in 'adaptaxes' or 'tight' mode.
%                   This factor might be useful to decrease or increase the
%                   estimated corrections.
%           Vector:
%                   Replace the automatic margin corrections by a vector
%                   containing custom corrections on each side of the
%                   figure frame, ordered as: [ left, bottom, right, top ].
%                   The values correspond to translations of the figure
%                   sides while maintaining the axes at a constant
%                   location. They are expressed in centimeters and applied
%                   to the figure obtained after the main figure resizing
%                   (i.e. the figure resized to match 'width' and/or
%                   'height'). The sign of the values matters: to increase
%                   the margins, the vector must be [ <0,<0, >0, >0 ].
%                   This option is useful to obtain a consistent resizing
%                   between similar figures (if 'activeposition' is set to
%                   'position').
%           Remark: 
%                   The vectorial version is allowed only for 7.x versions.
%                   It may have unpredictable behaviour for special
%                   figures, as described in 'tight' above.
%
%   matchcolorbars
%           True / False (default) to match the colorbars extent with their
%           related plot extent. Complementary to 'adaptaxes'. Should
%           always be used with 'adaptaxes' for versions older than 7. Does
%           not work for 7.x versions since the field linking colorbars and
%           plots has disappeared.
%
%   keeptextin
%           True / False (default) to keep the comment text boxes inside
%           their parent axes. Shift the boxes horizontally or vertically 
%           if they cross the axes boundary.
%
%   movelegto
%           If not empty (default), move all the legends to the given
%           location (see 'help legend' for details).
%
%   lockaxesaa
%           Same principle as 'lockaxes', but applied during the axes or 
%           margin adaptation process. Mostly useful when 'tight' option
%           is used, to avoid clipping of edge tick labels. Default: true.
%
% COLORS and LINE STYLES
% 
%   colormap
%           Apply a given colormap to the figure. If a string is given, it
%           must be the same input as the COLORMAP function of Matlab.
%           Otherwise, the color map array must be given. Applied before
%           the 'color' option in the execution of the code. Default: [].
%
%   color
%           One of the strings:
%
%           'bw'    
%                   Lines and text are colored in black and all other
%                   objects in grayscale
%           'gray'  
%                   All objects are converted into grayscale, with scaling
%                   based on the current colors, not on the current values.
%                   Set 'colormap' option to 'gray' beforehand if 
%                   necessary.
%           'bwtl'
%                   Text and lines are converted in black, other things not
%                   modified
%           'rgb'  
%                   All objects are left as given (Default).
%
%           Linked to: 'colormap' and 'stylemap'.
%
%   stylemap    
%           Specifies how to map solid line colors to styles. One of:
%           
%           []
%                   No style change (default).
%           'bw'
%                   Built-in mapping that maps lines with the same color to
%                   the same style and otherwise cycles through the
%                   available styles.
%           mls
%                   Matlab line style, as a string (e.g. '-').
%
%           fh
%                   Function handle. The target function must take as input
%                   a cell array of line objects and output a cell array
%                   of line style strings.
%
%           Remark: only SOLID lines are modified by this option.
%
% FONTS, LINES and MARKERS
%   
%   fontmode
%           'scaled', 'fixed', [] (default). If [], the fonts are left as
%           they are.
%
%   fontsize
%           A positive scalar. In 'scaled' mode, the font size of each text
%           object is multiplied by 'fontsize'. In 'fixed' mode, all the
%           text objects are set to the font size given by 'fontsize'.
%           If [] in 'scaled' mode, a scaling factor is computed from the
%           figure resizing.
%           Default: []. Units: points (in 'fixed' mode).
%
%   fontsizemin, fontsizemax
%           Font size limits in 'scaled' mode.
%
%   linemode, linewidth, linewidthmin, linewidthmax
%           Equivalent to fonts for lines.
%
%   markermode, markersize, markersizemin, markersizemax
%           Equivalent to fonts for markers.
%
%
% MISCELLANEOUS
%
%   customcode
%           Allow inclusion of custom code within FORMATFIG at different
%           places. A 2-element cell array is expected: {'location','code'}
%           
%           'location'  
%                   Specifies where the code must be executed. Choice
%                   between 'top', 'postHid' (default), 'bot'. 'top' places
%                   the code at the top of formatfig, 'postHid' at the top
%                   but after the handle identification section and 'bot'
%                   at the very end of formatfig. When using 'postHid', the
%                   handles are available by classes in variables like
%                   allLines, allText, allAxes (...), so that NO deletion
%                   command should be used at that place.
%
%           'code'      
%                   Any code given as character string compatible with
%                   EVAL() is accepted.
%
%           Example: { 'postHid', 'set( allAxes, ''color'', ''k'' )' }
%
%   rmtitle
%           True / False (default) to remove all the axes titles.
%  
%
%  Last modification: Jonathan Rossel, 15.12.2010
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Modif log: (see file)

%
%       18.04.08    J.Rossel        Use a trick to avoid a bug in colorbar
%                                   management. If a text object containing
%                                   a string is related to a colorbar, then
%                                   its handle is reassigned to the label
%                                   field (x or y according to the
%                                   orientation of the bar) before
%                                   processing.
%
%       21.04.08    J.Rossel        Added the 'keeptextin' option.
%
%       22.04.08    J.Rossel        When using 'adaptaxes', the text box
%                                   units are set to an absolute unit to
%                                   prevent Matlab from randomly modifying
%                                   the box positions. The font scaling is
%                                   then applied and the units are restored
%                                   afterwards. Weird Matlab behaviour
%                                   anyway. 
%                                   Observable with log x-axis, data units
%                                   (xlabel shifted downwards).
%
%       29.04.08    J.Rossel        Added the 'lockticks' option.
%
%       29.10.08    J.Rossel        Corrected a bug in the exponent
%                                   detection
%
%       23.03.09    J.Rossel        findall has a bug in Matlab 7.8
%                                   Updating text units with findall looses
%                                   legends. 
%                                   Rem of 22.04.08 can't be reproduced
%                                   on 7.8. Combine both: remove the
%                                   process described in 22.04.08 for 
%                                   versions from 7.0.
%
%                                   results obtained for 'adaptaxes' with
%                                   large fonts were rubbish for 7.0 and
%                                   later. Use the new
%                                   ActivePositionProperty to replace the
%                                   whole functionality. Still colorbars
%                                   are not dealt with properly, but only
%                                   for figures generated on older Matlab
%                                   versions.
%
%                                   Bug for 'keeptextin' corrected. The
%                                   text boxes were not related correctly
%                                   to their parent axes.
%
%                                   'movelegto' option added.
%
%                                   'matchcolorbars' option added
%
%       14.04.09    J.Rossel        "oldactpos" undefined bug corrected.
%                                   That bug appeared in 7.x when calling
%                                   the routines with 'adaptaxes'=false.
%
%       17.04.09    J.Rossel        For 7.x, in special cases, the
%                                   automatic resizing does not work
%                                   properly: e.g. increasing fonts when
%                                   colorbar present and having long
%                                   colorbar ticklabels and colorbar text
%                                   labels. It seems that Matlab deals
%                                   better with figure resizing. So the
%                                   local function Local_AdaptAxes_7x has
%                                   been added. This also solves the
%                                   exponent problems (power of 10 being
%                                   clipped).
%
%       20.04.09    J.Rossel        Small bug corrected (appeared for
%                                   colorbars without labels).
%
%       10.06.09    J.Rossel        Modified options for coloring. Added
%                                   the 'colormap' option. 'stylemap'
%                                   applies to solid lines only.
%
%       20.10.09    J.Rossel        Set WindowStyle to Normal before
%                                   formatting for version above 7.x
%
%       17.11.09    J.Rossel        Restore Latex interpreter if lost
%                                   during saving. Applied at the end of
%                                   the formatting to avoid some bugs, but
%                                   might therefore be problematic.
%                                   
%                                   'activeposition' option. Useful if axes
%                                   must keep their alignement while being
%                                   resized.
%
%                                   'marginfactor': to be used with
%                                   'adaptaxes'.
%
%                                   'stylemap': allow unique Matlab style
%                                   input.
%
%       11.01.10    J.Rossel        bug in latex interpreter restoration
%                                   corrected.
%
%       22.04.10    A.Pitzschke	    correct bug with strfind when having cell with subcells
%
%       30.06.10    J.Rossel        'locklimits' added
%
%       11.10.10    J.Rossel        'customcode' added
%
%       12.10.10    J.Rossel        Use of 'activeposition' modified. Now
%                                   it is used independently of 'adaptaxes'.
%                                   To avoid using it, leave it empty.
%
%                                   Use of 'marginfactor' modified. Absolute
%                                   extensions in each direction can now be
%                                   given to get better control on final figure
%                                   and axes size. For 6.x, 'marginfactor' now
%                                   helps controlling the 'adaptaxes' option.
%
%                                   'adaptaxes' and 'keeptextin' can now be
%                                   used when font size is not modified.
%
%       05.11.10    J.Rossel        'adaptaxes' 7.x modified. Now works with
%                                   Position+TightInset instead of
%                                   OuterPosition (less margins, less risk
%                                   of problems due to corrupted outer
%                                   position).
%                                   Automatic margin correction for
%                                   'position' mode should be better.
%                                   'tight' option added
%
%       08.11.10    J.Rossel        'tight' option modified to 
%                                   allow proportion conservation.
%                                   'marginfactor' as a 4-column vectors
%                                   now really is the absolute correction
%                                   of the margins (for 'position' mode).
%
%       09.11.10    J.Rossel        'adaptaxes': better margin determination
%                                   by matching axes position with plotbox
%                                   beforehand (2D plots only).
%                                   Also, outsided legends are dealt with
%                                   correctly.
%                                   param struct returned as function output.
%                                   defaults: -1 replaced by [] for
%                                   consistency.
%                                   
%       10.11.10    J.Rossel        'paperunits' option added with default
%                                   value 'centimeters'
%
%       15.12.10    J.Rossel        'lockaxesaa' option added.
%
%       16.12.10    J.Rossel        patch for Matlab bug when locking log
%                                   axis.

function opts = formatfig(varargin);


%param structure
opts = struct( ...
    'width', [], ...            %figure size
    'height', [], ...
    'refobj', [], ...
    'activeposition', 'outerposition', ...
    'paperunits', 'centimeters', ...
    ...
    'lockaxes', false, ...      %locking
    'locklimits', false, ...
    'lockticks', false, ...
    ...
    'adaptaxes', false, ...     %margin adaptation and other size correction
    'tight', [], ...
    'marginfactor', 1, ...
    'lockaxesaa', true, ...
    'matchcolorbars', false, ...
    'keeptextin', false, ...    
    'movelegto', [], ...
    ...
    'colormap', [], ...         %colors
    'color', 'rgb', ...
    'stylemap', [], ...
    ...
    'fontmode', [], ...         %object sizes
    'fontsize', [], ...         
    'fontmin', 8, ...
    'fontmax', 60, ...
    'linemode', [], ...
    'linewidth', [], ...
    'linemin', 0.5, ...
    'linemax', 100, ...
    'markermode', [], ...
    'markersize', [], ...
    'markermin', 0.5, ...
    'markermax', 30, ...
    ...
    'customcode', {{}}, ...     %misc
    'rmtitle', false ...        
    );

if nargin == 0
    %empty call, to get opts.
    return
end

%figure handle
H = varargin{1};
varargin(1) = [];

%version
verstr = version;
majorver = str2num(verstr(1));


%check whether a param structure has been given
%and deal with it
if isstruct(varargin{1}),
    param_values = struct2cell(varargin{1});
    param_names = fieldnames(varargin{1});
    param = cell(1,2*length(param_names));
    param(1:2:end-1) = param_names;
    param(2:2:end) = param_values;
    varargin(1) = []; %remove the structure
    varargin = {param{:},varargin{:}}; %add the structure as a list
end

%check the fieldnames and fill the opts structure
fieldnamesS = fieldnames(opts);
for j=1:2:length(varargin)-1
    if any(strcmpi(fieldnamesS,varargin{j})),
        opts = subsasgn(opts,struct('type','.','subs',lower(varargin{j})),varargin{j+1});
    end
end

% make sure figure is up-to-date
drawnow;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%execute custom code if any

if ~isempty( opts.customcode ) & strncmpi( opts.customcode{1}, 't', 1 )

    eval( opts.customcode{2} );
    
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Process format
old.objs = {}; %kept to avoid too much recoding (JR)
old.prop = {};
old.values = {};

% JR: First of all: restore the link between the colorbars and their labels (if
% any). Required for size processing in 6.x versions. Maybe useful for 7.x
% (not sure), but don't do any harm anyway.
% Note: this requires to re-do the handle attribution, as something changes
% in the figure handles when relinking the colorbar labels.
%colorbar trick
%for some reasons (bug of most of Matlab versions) the label property of a text object
%for colorbars is lost when saving the figure. ie: you can add
%a label to a colorbar, but then the label is saved as a text
%object and the ylabel field of the colorbar contains a handle
%to an empty string text object! So...
allColorbars = findall( findall(H, 'type', 'axes'), 'tag', 'Colorbar');

for ii = 1 : length( allColorbars ),
    
    ht = findall( allColorbars(ii), 'Type', 'text' );
    t = get(ht,'String');
    ind = find(~strcmp('',t));
    if length(ind) == 1 & length(ht) > 0,
        %there is only one non-empty text string
        %assume it is the label
        %Re-assign the text handle to the label field
        pos = get(allColorbars(ii),'Position');
        if pos(3) > pos(4),
            %horizontal cb
            set(allColorbars(ii),'Xlabel',ht(ind));
        else
            %vertical cb
            set(allColorbars(ii),'Ylabel',ht(ind));
        end
    end
end

%store the handles (2nd part)
allLines  = findall(H, 'type', 'line');
allSolidLines = findall( allLines, 'LineStyle', '-' );
allText   = findall(H, 'type', 'text');
allAxes   = findall(H, 'type', 'axes');
allColorbars = findall(allAxes, 'tag', 'Colorbar');
allImages = findall(H, 'type', 'image');
allLights = findall(H, 'type', 'light');
allPatch  = findall(H, 'type', 'patch');
allSurf   = findall(H, 'type', 'surface');
allRect   = findall(H, 'type', 'rectangle');
allFont   = [allText; allAxes];
allColor  = [allLines; allText; allAxes; allLights];
allMarker = [allLines; allPatch; allSurf];
allEdge   = [allPatch; allSurf];
allCData  = [allImages; allPatch; allSurf];
%JR addition
tmp = strcmp(get(allAxes,'Tag'),'legend');
allLeg = allAxes(tmp); %legends only
allAxesNoLeg = allAxes(~tmp); %axes, but not legend

if ~isempty( opts.customcode ) & strncmpi( opts.customcode{1}, 'p', 1 )
    
    %execute custom code if any
    eval( opts.customcode{2} );
    
end

% lock axes limits, ticks and labels if requested
if opts.lockaxes
	
	list1 = {'X','Y','Z'};
    list2 = {'TickMode','TickLabelMode','LimMode'}; %NB: setting TickLabelMode to manual for log axis results in label corruption (whether this is a bug or not is arguable).
    locklist = cellstr( [ reshape( repmat( char( list1 )', length( list2 ), 1 ), [], 1 ), repmat( char( list2 ), length( list1 ), 1 ) ] )'; %XTick..., Y..., etc
    
    set( allAxesNoLeg, locklist, repmat( { 'manual' }, length( allAxesNoLeg ), length( locklist ) ) );
    
end

%JR addition
%lock ticks only (very useful for log axis, otherwise only the power of 10
%is displayed...)
if opts.lockticks

	list1 = {'X','Y','Z'};
    list2 = {'TickMode'};
    locklist = cellstr( [ reshape( repmat( char( list1 )', length( list2 ), 1 ), [], 1 ), repmat( char( list2 ), length( list1 ), 1 ) ] )'; %XTick..., Y..., etc
    
    set( allAxesNoLeg, locklist, repmat( { 'manual' }, length( allAxesNoLeg ), length( locklist ) ) );
    
    %Avoid a bug in Matlab: with log axis, setting 'tickmode' to 'manual' corrupts the labels.
    %This can be avoided by manually resetting the ticks with their original values:
    set( allAxesNoLeg, { 'XTick'; 'YTick'; 'ZTick' }, get( allAxesNoLeg, { 'XTick'; 'YTick'; 'ZTick' } ) );    

end

%JR addition
%lock axes limits only
if opts.locklimits

    list1 = {'X','Y','Z'};
    list2 = {'LimMode'};
    locklist = cellstr( [ reshape( repmat( char( list1 )', length( list2 ), 1 ), [], 1 ), repmat( char( list2 ), length( list1 ), 1 ) ] )'; %XLim..., Y..., etc
    
    set( allAxesNoLeg, locklist, repmat( { 'manual' }, length( allAxesNoLeg ), length( locklist ) ) );
    
end

%remove title
%JR addition
if opts.rmtitle,
    tmp = get(allAxes,'Title');
    if iscell(tmp), tmp = cell2mat(tmp); end
    allTitles = tmp;
    set(allTitles,'String',[]);
end

if majorver >= 7

    if ~isempty( opts.activeposition ),
        
        %JR: for Matlab 7 and above, set activepositionproperty before any
        %changes to let Matlab resize everything automatically. By default,
        %Outerposition is used. Position can also be used if axes alignment
        %must be preserved. Should be ok with adaptaxes local function, but
        %labels might be cropped.
        
        oldactpos = LocalGetAsCell( allAxesNoLeg, 'ActivePositionProperty' ); %keep for restore afterwards
        oldaxesunits = LocalGetAsCell( allAxesNoLeg, 'Units' );
       
        set( allAxesNoLeg, 'ActivePositionProperty', opts.activeposition, 'Units', 'Normalized' );
        
    elseif isempty( opts.activeposition ) & opts.adaptaxes ...
        & length( unique( LocalGetAsCell( allAxesNoLeg, 'ActivePositionProperty' ) ) ) > 1
        
        disp( [ '!!! When using ''adaptaxes'', all the axes should have the same ''ActivePositionProperty'' ', ...
                'or an ''activeposition'' option should be given as well. ''adaptaxes'' might fail. !!!' ] );
        
    end
    
end

% Process figure size parameters
%NB: only the figure dimensions are modified directly.
%The axes dimensions are adapted by Matlab automatically.

if majorver >= 7,
    %JR: figures must be undocked first
    set( H, 'WindowStyle', 'Normal' );
end    

if ~isempty( opts.paperunits )
    set( H, 'PaperUnits', opts.paperunits );
    figurePaperUnits = opts.paperunits;
else    
    figurePaperUnits = get(H, 'PaperUnits');
end
oldFigureUnits = get(H, 'Units');
oldFigPos = get(H,'Position');
set(H, 'Units', figurePaperUnits);
figPos = get(H,'Position');
refsize = figPos(3:4);
if ~isempty( opts.refobj )
    oldUnits = get(opts.refobj, 'Units');
    set(opts.refobj, 'Units', figurePaperUnits); %make sure to have absolute units
    r = get(opts.refobj, 'Position');
    refsize = r(3:4);
    set(opts.refobj, 'Units', oldUnits);
end
aspectRatio = refsize(1)/refsize(2); %width over height
if isempty( opts.width ) & isempty( opts.height )
    opts.width = refsize(1);
    opts.height = refsize(2);
elseif isempty( opts.width )
    opts.width = opts.height * aspectRatio;
elseif isempty( opts.height )
    opts.height = opts.width / aspectRatio;
end
wscale = opts.width/refsize(1);
hscale = opts.height/refsize(2);
sizescale = min(wscale,hscale);
set(H, 'PaperPositionMode', 'auto'); %computer screen used as ref, implies larger eps file if the figure is larger on screen than on paper (for zbuffer or opengl)
newPos = [figPos(1) figPos(2)+figPos(4)*(1-hscale) ...
        wscale*figPos(3) hscale*figPos(4)]; %newpos on screen and on paper
set(H, 'Position', newPos);
set(H, 'Units', oldFigureUnits);
drawnow; %need to be called after resizing window

% Process color

%JR: colormap option
if ~isempty( opts.colormap ),
    
    if ischar( opts.colormap ),
        opts.colormap = colormap( opts.colormap );
    end
    
    set( H, 'Colormap', opts.colormap );
    
end

if any(strcmp(opts.color,{'bw', 'gray'})),
    
    %compute and set gray colormap
    oldcmap = get(H,'Colormap');
    newgrays = 0.30*oldcmap(:,1) + 0.59*oldcmap(:,2) + 0.11*oldcmap(:,3);
    newcmap = [newgrays newgrays newgrays];
    old = LocalPushOldData(old, H, 'Colormap', oldcmap);
    set(H, 'Colormap', newcmap); %JR: modifies the handle name for some reasons
    
    %JR: redefine handles
    allImages = findall(H, 'type', 'image');
    allPatch  = findall(H, 'type', 'patch');
    allSurf   = findall(H, 'type', 'surface');
    allCData  = [allImages; allPatch; allSurf];
   
    %compute and set ColorSpec and CData properties to gray
    old = LocalUpdateColors(allColor, 'color', old);
    old = LocalUpdateColors(allAxes, 'xcolor', old);
    old = LocalUpdateColors(allAxes, 'ycolor', old);
    old = LocalUpdateColors(allAxes, 'zcolor', old);
    old = LocalUpdateColors(allMarker, 'MarkerEdgeColor', old);
    old = LocalUpdateColors(allMarker, 'MarkerFaceColor', old);
    old = LocalUpdateColors(allEdge, 'EdgeColor', old);
    old = LocalUpdateColors(allEdge, 'FaceColor', old);
    old = LocalUpdateColors(allCData, 'CData', old); %useful if absolute RGB colors given instead of relative colormap values    
    
end

% Process font parameters
if ~isempty(opts.fontmode)
    oldfonts = LocalGetAsCell(allFont,'FontSize');
    oldfontunits = LocalGetAsCell(allFont,'FontUnits');
    
    if opts.adaptaxes & majorver < 7,
        
        %JR addition: change text units before scaling fonts to avoid
        %(random) repositioning by Matlab if adaptaxes is on and Matlab version
        %below 7.

        oldtextunits = LocalGetAsCell(allText,'Units');
        set(allText,'Units','Centimeters'); %applied only during font resizing
        
    end
    
    switch (opts.fontmode)
        case 'fixed'
            if ~isempty(opts.fontsize),
                set(allFont,'FontUnits','points'); %modif: used for 'fixed' before applying size
                
                %JR addition: assess a scale factor
                tmp = get(allFont,'FontSize');
                if iscell(tmp), tmp = cell2mat(tmp); end
                oldfontsinpoints = tmp;
                fontscale = mean(opts.fontsize ./ oldfontsinpoints);
                
                set(allFont,'FontSize',opts.fontsize);
            end
        case 'scaled'
            if isempty(opts.fontsize)
                fontscale = sizescale;
            else
                fontscale = opts.fontsize;
            end
            newfonts = LocalScale(oldfonts,fontscale,opts.fontmin,opts.fontmax);
            set(allFont,{'FontSize'},newfonts);
            set(allFont,'FontUnits','points'); %modif: used for 'scaled' after applying size. Needed because of axes resizing (below).
        otherwise
            error('Invalid FontMode parameter');
    end

end
    
%JR addition: adapt axes to avoid label overlapping or cropping

if opts.adaptaxes | ~isempty( opts.tight ) | length( opts.marginfactor ) > 1 | opts.marginfactor(1) ~= 1,
    
    if majorver < 7 & ( opts.adaptaxes | opts.marginfactor(1) ~= 1 ),
        %6.x

        %reset text units (cf above)
        if ~isempty(opts.fontmode)
            set(allText,{'Units'},oldtextunits);
        end

        %adapt axes
        adaptscale = 0;
        if ~isempty(opts.fontmode)
            adaptscale = fontscale;
        end
        adaptscale = opts.marginfactor .* max( [ adaptscale, 1./sizescale ] ); 
        %NB: previously only fontscale was used, but it might happen that the fonts remain the same while the figure size is reduced.
        %In that case, this is equivalent to a relative increase of font size equal to 1/sizescale.
        Local_AdaptAxes_6x( allAxesNoLeg, adaptscale );
    
    else
        %7.x
        %for 7 and above, Matlab should deal with it properly after
        %correct activation of ActivePositionProperty. But... in some
        %cases, what Matlab should do and what Matlab does are 2
        %differents things... For example, text labels of colorbars are
        %still cropped when the font size is increased and if the
        %ticklabels are long.
        %Workaround: Matlab seems much smarter during figure resizing
        %than during font resizing. So: set absolute units, increase
        %figure size to include all labels, set normalized units,
        %restore figure size.
        %This method also works when keeping 'position' option.
        
        Local_AdaptAxes_7x( H, allAxesNoLeg, allLeg, opts.marginfactor, opts.tight, opts.lockaxesaa );
        
    end
    
    
    %if there is a resize function (usually when legends are present),
    %call it to reposition the legends
    rf = get(H,'ResizeFcn');
    if ~isempty(rf),
        eval(rf);
    end
    
end %option adapt

%Match colorbars
if opts.matchcolorbars,
        
    if majorver >= 7,

        disp( 'If you know where to find the field linking a colorbar and its plot, let me know!!!')
        warning( 'Setting (outer)position makes it the active one!' );

    else

        %match colorbars with their related plot
        Local_MatchColorBars( allAxesNoLeg );

    end

end

%JR addition: force text boxes to stay inside its parent axes
if opts.keeptextin,
    %loop on axes (not legend)
    for ii = 1:length(allAxesNoLeg),
        if ~isempty(get(allAxesNoLeg(ii),'ZTickLabel')),
            %3D plot
            %don't do anything
            continue
        end
        
        %get children text boxes handles (no legend, no labels)
        inText = findobj( allAxesNoLeg(ii), 'type', 'text'); %all accessible (findall=wrong!) text box children of current axes
        tmp = get(inText,'Parent');
        if length(tmp) > 1, tmp = cell2mat(tmp); end
        tmp = find( strncmpi(get(tmp,'Tag'),'legend',6) | strncmpi(get(inText,'Tag'),'legend',6) );
        inText(tmp) = []; %don't consider legends. The autosize function can be used for them.
        
        for jj = 1:length(inText),
            oldun = get(inText(jj),'Units');
            set(inText(jj),'units','normalized');
            ex = get(inText(jj),'extent');
            pos = get(inText(jj),'position');
            
            %check oversized boxes
            %the "too wide" or "too high" cases cannot be dealt with
            %automatically, the phrase must be rewritten accordingly...
            %Reposition in a way that avoid dealing with the alignment
            %properties
            if ex(1) < 0,
                %out on the left
                pos(1) = pos(1) + abs(ex(1));
            end
            if ex(1)+ex(3) > 1,
                %out on the right
                pos(1) = pos(1) - (ex(1) + ex(3) - 1);
            end
            if ex(2) < 0,
                %out at the bottom
                pos(2) = pos(2) + abs(ex(2));
            end
            if ex(2) + ex(4) > 1,
                %out at the top
                pos(2) = pos(2) - (ex(2) + ex(4) - 1);
            end
            
            %apply changes
            set(inText(jj),'Position',pos);
            
            %restore units
            set(inText(jj),'Units',oldun);
            
        end %loop inText
    end %loop axes
end %option keeptextin


%JR: move legends if required
if ~isempty( opts.movelegto ),
    
    set( allLeg, 'Location', opts.movelegto );
    
end

if majorver >= 7 & ~isempty( opts.activeposition ),
    %restore actpos and axes units
    if ~iscell(oldactpos), oldactpos = {oldactpos}; end
    if ~iscell(oldaxesunits), oldaxesunits = {oldaxesunits}; end
    set(allAxesNoLeg,{'ActivePositionProperty'},oldactpos,{'Units'},oldaxesunits);
end

% Process line parameters
if ~isempty(opts.linemode)
    oldlines = LocalGetAsCell(allMarker,'LineWidth');
    old = LocalPushOldData(old, allMarker, {'LineWidth'}, oldlines);
    switch (opts.linemode)
        case 'fixed'
            if ~isempty(opts.linewidth)
                set(allMarker,'LineWidth',opts.linewidth);
            end
        case 'scaled'
            if isempty(opts.linewidth)
                scale = sizescale;
            else
                scale = opts.linewidth;
            end
            newlines = LocalScale(oldlines, scale, opts.linemin, opts.linemax);
            set(allMarker,{'LineWidth'},newlines);
    end
end

% Process line-markers parameters
%JR addition
if ~isempty(opts.markermode)
    oldmarkers = LocalGetAsCell(allLines,'MarkerSize');
    old = LocalPushOldData(old, allLines, {'MarkerSize'}, oldmarkers);
    switch (opts.markermode)
        case 'fixed'
            if ~isempty(opts.markersize)
                set(allLines,'MarkerSize',opts.markersize);
            end
        case 'scaled'
            if isempty(opts.markersize)
                scale = sizescale;
            else
                scale = opts.markersize;
            end
            newmarkers = LocalScale(oldmarkers, scale, opts.markermin, opts.markermax);
            set(allLines,{'MarkerSize'},newmarkers);
    end
end

% process line-style map
%JR: Must appear here due to a strange recoloring of the legends
%when changing font size (thanks to Matlab's programmers)
if ~isempty(opts.stylemap)
    if ischar(opts.stylemap),
        if strcmpi(opts.stylemap,'bw')
            newlstyle = LocalMapColorToStyle(allSolidLines);
        else
            %JR: allow uniform linestyle, include all solide lines
            allSolidLines = findall(H,'linestyle','-');
            newlstyle = {opts.stylemap};
        end
        if ~isempty(allSolidLines)
            set(allSolidLines,{'LineStyle'},newlstyle);
        end
    else
        try
            newlstyle = feval(opts.stylemap,allSolidLines);
            set(allSolidLines,{'LineStyle'},newlstyle);
        catch
            warning(['Skipping stylemap. ' lasterr]);
        end
    end
end

%JR: coloring option re-designed: line and text to black
%Must appear here due to a strange recoloring of the legends
%when changing font size (thanks to Matlab's programmers)
if any(strcmp(opts.color,{'bw', 'bwtl'})),

    %Set lines and texts to black
    set( [ allText; allLines ], 'color', 'k' );
    
end

%JR: Set Latex interpreter. This option is sometimes lost when saving the
%figure, especially for colorbars. This should appear at the beginning
%so that these latex strings are taken into account during axes resizing
%processes. The problem is that the latex text boxes have corrupted
%'extent' properties which causes problems during axes resizing (the axes
%outerposition is largely overestimated).
textstr = LocalGetAsCell( allText, 'string', false ); %get all the strings in cell array
for ii = 1 : length( textstr ),
    % APi: eliminate subcells, otherwise strfind crashes
    if iscell(textstr{ii})==1,
    	textstr{ii}=char(textstr{ii});
    end
    %make sure that all strings appear on 1 row only, otherwise strfind
    %fails.
    if size( textstr{ ii }, 1 ) > 1,
        textstr{ ii } = textstr{ ii }( : )'; %the text itself doesn't matter. Only the presence of $ is important.
    end
end
mathsym = strfind( textstr, '$' ); %cell array. Empty if symbol not found.
for jj = 1 : length( mathsym ),
    if ~isempty( mathsym{ jj } ),
        set( allText( jj ), 'interpreter', 'latex' );
    end
end

if ~isempty( opts.customcode ) & strncmpi( opts.customcode{1}, 'b', 1 )
    
    %execute custom code if any
    eval( opts.customcode{2} );
    
end

%Update figure
drawnow;

%
%  Local Functions
%

function outData = LocalPushOldData(inData, objs, prop, values)
outData.objs = {objs, inData.objs{:}};
outData.prop = {prop, inData.prop{:}};
outData.values = {values, inData.values{:}};

function cellArray = LocalGetAsCell(fig,prop,allowemptycell);
cellArray = get(fig,prop);
if nargin < 3
    allowemptycell = 0;
end
if ~iscell(cellArray) & (allowemptycell | ~isempty(cellArray))
    cellArray = {cellArray};
end

function newArray = LocalScale(inArray, scale, minv, maxv)
n = length(inArray);
newArray = cell(n,1);
for k=1:n
    newArray{k} = min(maxv,max(minv,scale*inArray{k}(1)));
end

function gray = LocalMapToGray1(color)
gray = color;
if ischar(color)
    switch color(1)
        case 'y'
            color = [1 1 0];
        case 'm'
            color = [1 0 1];
        case 'c'
            color = [0 1 1];
        case 'r'
            color = [1 0 0];
        case 'g'
            color = [0 1 0];
        case 'b'
            color = [0 0 1];
        case 'w'
            color = [1 1 1];
        case 'k'
            color = [0 0 0];
    end
end
if ~ischar(color)
    gray = 0.30*color(1) + 0.59*color(2) + 0.11*color(3);
end

function newArray = LocalMapToGray(inArray);
n = length(inArray);
newArray = cell(n,1);
for k=1:n
    color = inArray{k};
    if ~isempty(color)
        color = LocalMapToGray1(color);
    end
    if isempty(color) | ischar(color)
        newArray{k} = color;
    else
        newArray{k} = [color color color];
    end
end

function newArray = LocalMapColorToStyle(inArray);
inArray = LocalGetAsCell(inArray,'Color');
n = length(inArray);
newArray = cell(n,1);
styles = {'-','-.','--',':'};
uniques = [];
nstyles = length(styles);
for k=1:n
    gray = LocalMapToGray1(inArray{k});
    if isempty(gray) | ischar(gray) | gray < .05
        newArray{k} = '-';
    else
        if ~isempty(uniques) & any(gray == uniques)
            ind = find(gray==uniques);
        else
            uniques = [uniques gray];
            ind = length(uniques);
        end
        newArray{k} = styles{mod(ind-1,nstyles)+1};
    end
end

function [ newArray, haschanged ] = LocalMapCData(inArray);
n = length(inArray);
newArray = cell(n,1);
haschanged = false;
for k=1:n
    color = inArray{k};
    if (ndims(color) == 3) & isa(color,'double')
        haschanged = true;
        gray = 0.30*color(:,:,1) + 0.59*color(:,:,2) + 0.11*color(:,:,3);
        color(:,:,1) = gray;
        color(:,:,2) = gray;
        color(:,:,3) = gray;
    end
    newArray{k} = color;
end

function outData = LocalUpdateColors(inArray, prop, inData)
value = LocalGetAsCell(inArray,prop);
outData.objs = {inData.objs{:}, inArray};
outData.prop = {inData.prop{:}, {prop}};
outData.values = {inData.values{:}, value};
if (~isempty(value))
    if strcmp(prop,'CData') 
        [ value, haschanged ] = LocalMapCData(value);
        %JR modif: add haschanged test to avoid
        %problems when redefining colors of patches based
        %on colormaps
        if ~haschanged, return; end
    else
        value = LocalMapToGray(value);
    end
    set(inArray,{prop},value);
end

function Local_AdaptAxes_6x( targAxes, fontscale );
    
    %targAxes: considered axes
    
    %Idea: as axes can be multiple and positioned anywhere, the
    %resizing is done on the axes in a way that keeps the overall
    %outside boundary nearly constant.
    %The fontscale factor is used to increase the distance from the
    %axes to the labels. The increase of size of the label is balanced
    %by shifting both the label and the axes. The shift and the space
    %increase are balanced by reducing the size of the axes.
    %The power of 10 (a real pain in the ...) is approximately
    %accounted for.
    %
   
    %store axes units and reset
    oldunits = get(targAxes,'Units');
    set(targAxes,'Units','centimeters');
        
    %loop on axes (not legend)
    for ii = 1:length(targAxes),
        if ~isempty(get(targAxes(ii),'ZTickLabel')),
            %3D plot
            %don't do anything
            continue
        end

        %store axes position
        oldpos = get(targAxes(ii),'Position');

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %x-axis
        xexp = false;
        if ~isempty(get(targAxes(ii),'XTickLabel')),
            %there are xticklabels
            ticklab = true;

            %find if an exponent is used
            tmp = get(targAxes(ii),'XTickLabel');
            if iscell(tmp), tmp = cell2mat(tmp); end
            ticklabval = str2num(tmp);
            if ~isempty(ticklabval),
                %values are numerical
                %compare them to tick values, use mean because
                %perfect agreement is not required
                tv = get(targAxes(ii),'XTick');
                mtv = mean(abs(tv));
                mtl = mean(abs(ticklabval));
                if mtv/mtl > 5 | mtl/mtv > 5,
                    %the value is not contained in the interval limit
                    %an exponent is displayed at the end of the axis
                    %vertically, under the last ticklabel. Always
                    %displayed at the bottom of the axes. (even if
                    %labels are at the top!).
                    xexp = true;
                end
            end

        else
            ticklab = false;
        end
        axloc = get(targAxes(ii),'XAxisLocation');
        axlabel = get(targAxes(ii),'XLabel');
        %change label units and alignement (initiated even if empty!)
        set(axlabel,'Units','centimeters','HorizontalAlignment','center');
        if strcmp(axloc,'bottom'),
            set(axlabel,'VerticalAlignment','top');
        else
            set(axlabel,'VerticalAlignment','bottom');
        end
        oldposlabel = get(axlabel,'Position');
        if ~isempty(get(axlabel,'String')),
            %there is a label string (NB: there is always a label, even
            %if the string is empty)
            labelstr = true;
        else
            labelstr = false;
        end

        %init variables
        newpos = oldpos;
        newposlabelx = oldposlabel;
        labextent = get(axlabel,'Extent');
        applychanges = false;
        xaxlabel = axlabel;

        if ticklab | labelstr,

            if labelstr,
                labelshift = labextent(4)*(1-1/fontscale); %size increase wrt position

                if strcmp(axloc,'bottom'),
                    %more room done at the bottom, so no need to do more for
                    %the exponent
                    xexp = false;
                end
            else
                labelshift = 0;
            end

            %define new positions
            if strcmp(axloc,'bottom'),

                disttolab = abs(newposlabelx(2)) * fontscale; %new distance to label from axes

                %position of label center wrt absolute position
                newposlabelx(2) = -disttolab;

                %position of axes
                %add the diff betw the dist to lab and the label
                %shift
                newpos(2) = newpos(2) + disttolab - abs(oldposlabel(2)) + labelshift;
                newpos(4) = newpos(4) - (newpos(2) - oldpos(2)); %resize to keep roof at same position

            else %top
                disttolab = (newposlabelx(2) - oldpos(4)) * fontscale; %new distance to label from axes

                newpos(4) = oldpos(4) - (disttolab - (oldposlabel(2)-oldpos(4)) + labelshift);

                %position of label center
                newposlabelx(2) = newpos(4) + disttolab;

                %more room done at the top, so no need to do more for
                %the exponent
                yexp = false;
            end

            %apply changes
            applychanges = true;
        end %xlabel adaptation

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %y-axis
        yexp = false;
        if ~isempty(get(targAxes(ii),'YTickLabel')),
            %there are yticklabels
            ticklab = true;

            %find if an exponent is used
            tmp = get(targAxes(ii),'YTickLabel');
            if iscell(tmp), tmp = cell2mat(tmp); end
            ticklabval = str2num(tmp);
            if ~isempty(ticklabval),
                %values are numerical
                %compare them to tick values, use mean because
                %perfect agreement is not required
                tv = get(targAxes(ii),'YTick');
                mtv = mean(abs(tv));
                mtl = mean(abs(ticklabval));
                if mtv/mtl > 5 | mtl/mtv > 5,
                    %the value is not contained in the interval limit
                    %an exponent is displayed at the end of the axis
                    yexp = true;
                end
            end

        else
            ticklab = false;
        end
        axloc = get(targAxes(ii),'YAxisLocation');
        axlabel = get(targAxes(ii),'YLabel');
        %change label units and alignement (initiated even if empty!)
        set(axlabel,'Units','centimeters','HorizontalAlignment','center');
        if strcmp(axloc,'left'),
            set(axlabel,'VerticalAlignment','bottom');
        else
            set(axlabel,'VerticalAlignment','top');
        end
        oldposlabel = get(axlabel,'Position');
        if ~isempty(get(axlabel,'String')),
            %there is a label string (NB: there is always a label, even
            %if the string is empty)
            labelstr = true;
        else
            labelstr = false;
        end

        %init variables
        newposlabely = oldposlabel;
        labextent = get(axlabel,'Extent');
        yaxlabel = axlabel;

        if ticklab | labelstr,

            if labelstr,
                labelshift = labextent(3)*(1-1/fontscale); %size increase wrt position
            else
                labelshift = 0;
            end

            %define new positions
            if strcmp(axloc,'left'),

                disttolab = abs(newposlabely(1)) * fontscale; %new distance to label from axes

                %position of label center wrt absolute position
                newposlabely(1) = -disttolab;

                %position of axes
                %add the diff betw the dist to lab and the label
                %shift
                newpos(1) = newpos(1) + disttolab - abs(oldposlabel(1)) + labelshift;
                newpos(3) = newpos(3) - (newpos(1) - oldpos(1)); %resize to keep roof at same position

            else %right
                disttolab = (newposlabely(1) - oldpos(3)) * fontscale; %new distance to label from axes

                newpos(3) = oldpos(3) - (disttolab - (oldposlabel(1)-oldpos(3)) + labelshift);

                %position of label center wrt absolute position
                newposlabely(1) = newpos(3) + disttolab;

            end

            %apply changes
            applychanges = true;
        end %ylabel adaptation

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %apply changes
        %changes due to exponents
        if xexp | yexp,
            %estimate width of the exponent part
            newfts = get(targAxes(ii),'FontSize');
            oldfts = newfts / fontscale;
            additionallength = 1.5*(newfts - oldfts) * 1/72 * 2.54; %from points to cm                
        end
        if xexp,
            %here: there is an exp on the x axis and there is no
            %xlabel at the bottom

            %decrease height and shift upwards
            newpos(2) = newpos(2) + additionallength;
            newpos(4) = newpos(4) - additionallength;
            newposlabelx(2) = newposlabelx(2) - additionallength;
        end
        if yexp,
            %here: there is an exp on the y axis and the x-axis is at
            %the bottom, or it is at the top without labels

            %decrease height
            newpos(4) = newpos(4) - additionallength;
        end

        if applychanges,
            set(targAxes(ii),'Position',newpos);

            %center labels
            newposlabelx(1) = newpos(3)/2;
            newposlabely(2) = newpos(4)/2;

            %apply label position
            set(xaxlabel,'Position',newposlabelx);
            set(yaxlabel,'Position',newposlabely);
        end
    end %loop for adaptation
    
    %restore axes units
    if ~iscell(oldunits), oldunits = {oldunits}; end
    set(targAxes,{'Units'},oldunits);
        
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Local_AdaptAxes_7x( H, allAxesNoLeg, allLeg, marginfactor, tight, blnLockAxes, blnInnerCall );
    
    %Idea: to complete Matlab standard (usually ok for Outerposition mode but not for the Position mode)
    %treatment, make sure that all the axes Outerpositions are given within
    %the figure (if a label is cropped, the outerposition will go outside
    %the figure). So:
    %Loop on all axes and store the required additionnal length on all
    %sides of the figure. Add it with axes in absolute units, change units
    %to normalized and come back to original size.
    %The idea is to increase the relative size of the margins through this
    %process.
    %
    %New mode: marginfactor as a vector of absolute corrections in cm
    %to allow conservation of size between figures
    %
    %New (05.11.10): use position+tightinset instead of outerposition.
    %According to Matlab's help, in outerposition mode, it is not
    %outerposition that is used, but position+tightinset (... confusing!)
    %It is sufficient to keep position+tightinset inside. It doesn't
    %matter if outerposition is cropped. This choice is better, 
    %since it results in less margin and there is a more direct observation
    %of figure corruption (in some cases, outerposition might already be
    %bad on the original figure without any particular symptoms since
    %tightinset+position is ok...). This results in an additional
    %difficulty: just increasing the margin to fit the tightinset is not
    %enough, the figure reduction factor must be taken into account
    %otherwise the labels will always be cropped. This last point is
    %relevant only for 'position' mode.
    %
    %Also new: tight option
    %
    %New: now ok for legends outside axes. Necessary since these legends
    %   are not included in tightinset...
    %
    %15.12.10: lock axes graduation beforehand to avoid clipping of re-appearing ticklabels at tips of axis
    
    %init
    if nargin < 7, blnInnerCall = false; end
    allAxesNoLegNoOL = findall(allAxesNoLeg, 'flat', '-not', 'tag', 'scribeOverlay' ); %remove hidden axes that prevents correct correction determination
    allLegNoLoc = findall( allLeg, 'flat', 'location', 'none' ); %legends with positionning not influenced by axes positionning.
    legloc = strtrim( cellstr( fliplr( char( LocalGetAsCell( allLeg, 'location' ) ) ) ) ); %legend locations, flipped l-r
    allLegOut = allLeg( strmatch( fliplr( 'Outside' ), legloc ) ); %legends with defined location and outside the plot.  
    allLegTarget = [ allLegNoLoc; allLegOut ]; %legends with defined location inside plots are not important for axes adaptation and therefore avoided.
    
    %lock axes limits, ticks and labels to avoid modification of
    %axis tips during resizing (otherwise, a new tick might appear at the end
    %of an axis during the last resizing and therefore be cropped).
    if blnLockAxes

        list1 = { 'X', 'Y', 'Z' };
        %list2 = { 'TickMode', 'TickLabelMode', 'LimMode' };
        list2 = { 'TickMode', 'LimMode' }; %NB: setting TickLabelMode to manual for log axis results in label corruption (whether this is a bug or not is arguable). Not necessary here, just don't do it.
        locklist = cellstr( [ reshape( repmat( char( list1 )', length( list2 ), 1 ), [], 1 ), repmat( char( list2 ), length( list1 ), 1 ) ] )'; %XTick..., Y..., etc
        %oldlock = get( allAxesNoLegNoOL, locklist ); % nhandles x nProps cell array. NB: not used since restoring a posteriori results in re-calculation of ticks by Matlab and therefore recreates the problem.
        set( allAxesNoLegNoOL, locklist, repmat( { 'manual' }, length( allAxesNoLegNoOL ), length( locklist ) ) );
        
        %Avoid a bug in Matlab: with log axis, setting 'tickmode' to 'manual' corrupts the labels.
        %This can be avoided by manually resetting the ticks with their original values:
        set( allAxesNoLegNoOL, { 'XTick'; 'YTick'; 'ZTick' }, get( allAxesNoLegNoOL, { 'XTick'; 'YTick'; 'ZTick' } ) );    
    
    end    
        
    %store 
    oldaxesunits = LocalGetAsCell( allAxesNoLeg, 'Units' );
    oldlegunits = LocalGetAsCell( allLegTarget, 'Units' );
    oldfigunits = get( H, 'units' );
    oldactpos = LocalGetAsCell( allAxesNoLeg, 'ActivePositionProperty' ); %keep for restore afterwards. Necessary because automatically changed when resetting axes position for unknown reasons.
        
    %Set same absolute units for figure and axes (avoid axes redim when figure is resized)
    set( H, 'Units', 'centimeters' );
    set( allAxesNoLeg, 'Units', 'centimeters' );
    set( allLegTarget, 'Units', 'centimeters' );
    
    %store original figure position (in centimeters)
    fpos = get( H, 'Position' );
    
    %Match axes position with plotbox to avoid problem of margin determination for special plots
    %Hopefully that won't create new problems. It might in case of multiple subplots
    %since outerposition is modified in the process, but can't be restored
    %without cancelling the axes position modification...!
    %Not done for 3D plots (might be done, but need to understand how that works...)
    
    for ii = 1 : length( allAxesNoLegNoOL )
        
        h = allAxesNoLegNoOL( ii );
        
        if ~isempty( get( h, 'ZTickLabel' ) ),
            %3D plot
            %don't do anything
            continue
        end
        
        pbar = get( h, 'PlotBoxAspectRatio' ); %NB: this aspect ratio is given for absolute coordinates. OK here since h is in centimeters.
            
        if strcmpi( get( h, 'PlotBoxAspectRatioMode' ), 'manual' ) | any( pbar( 1 : 2 ) ~= 1 )
        
            %done only if manual or not [1,1,?]. Otherwise, the value stored in pbar don't match
            %the actual plot box aspect (due to stretch-to-fill mode).
            
            axpos = get( h, 'position' );
            %axopos = get( h, 'outerposition' ); %store it. Restored after the matching to avoid possible problems with subplots. NOTE: cf below.
            axarf = axpos(4) / axpos(3); %axes aspect ratio factor. Height over width.
            pbarf = pbar(2) / pbar(1); %plot box aspect ratio factor.
            
            if pbarf == axarf
                %already matching
                continue
            end
            
            if pbarf > axarf
            
                %axes is wider than plot box but same height (only possibility since plot box must be contained in axes and one dimension is equal)
                %Corr axes width
                
                newwidth = axpos(4) ./ pbarf;
                axpos(1) = axpos(1) + ( axpos(3) - newwidth ) ./ 2; %correct the axes positioning
                axpos(3) = newwidth; %correct the axes extension
            
            elseif pbarf < axarf
            
                %axes is higher than plot box but same width (only possibility since plot box must be contained in axes and one dimension is equal)
                %Corr axes height
                
                newheight = axpos(3) .* pbarf;
                axpos(2) = axpos(2) + ( axpos(4) - newheight ) ./ 2; %correct the axes positioning
                axpos(4) = newheight; %correct the axes extension
            
            end
            
            set( h, 'position', axpos ); %set the new position. activepositionproperty is restored in a single call below.
            %set( h, 'outerposition', axopos ); %restore outerposition. No reason to modify it here. NOTE: this resets the axes position for unknown reasons. => don't do it.
            
        end
        
    end
    
    %restore active position to counteract unwanted modifications resulting from plotbox matching above
    set( allAxesNoLeg, { 'ActivePositionProperty' }, oldactpos );
            
        
    if ~isempty( tight )
        
        %Tight bounding
        
        %addpos will contain the length to add (or usually remove) on each side of the figure
        %addpos(1,2) is positive to remove margin and negative to add it
        %(this has to be understand as something to add to the figure
        %boundary in absolute coordinates on the screen, while maintaining
        %the axes at the same position)
        addpos = [ inf, inf, -inf, -inf ];
        
    else

        %addpos will contain the length to add on each side of the figure
        %addpos(1,2) is negative (if not zero)
        addpos = zeros( 1, 4 );
    
    end
        
    if length( marginfactor ) > 1
        
        %use directly marginfactor
        addpos = marginfactor;
        
        if ~isempty( tight ) & ~strcmpi( tight, 'xy' )
            disp( 'Warning: ''tight'' is not empty but absolute marginfactor given.' )
            disp( '   This will result in scaling conservation (at least for ''position'' mode) but not tight margins.' );
        end
        
    else
        
        %standard mode: determines automatically the required correction
        
        for ii = 1 : length( allAxesNoLegNoOL ),

            %tightinset frame:
            apos = get( allAxesNoLegNoOL( ii ), 'Position' ); %axes position
            timargin = get( allAxesNoLegNoOL( ii ), 'TightInset' ); %margins for tight inset frame
            tipos = apos + [ -timargin( 1 : 2 ), timargin( 1 : 2 ) + timargin( 3 : 4 ) ]; %remove margin for position and addup margins for extension
            
            addpos = [ min( addpos(1), tipos(1) ), ...
                min( addpos(2), tipos(2) ), ...
                max( addpos(3), sum( tipos( [ 1, 3 ] ) ) - fpos(3) ), ...
                max( addpos(4), sum( tipos( [ 2, 4 ] ) ) - fpos(4) ) ];
        end
        
        for ii = 1 : length( allLegTarget ),
        
            %for legends, 'position' must be used, but a 0.1 additionnal margin is
            %added to avoid problems related to constant extent of legends during
            %resizing.
            %This loop is necessary for legends that are outside axes.
            apos = get( allLegTarget( ii ), 'Position' ); %legend position
            apos = apos + 0.1 * [ -1, -1, 2, 2 ]; %additionnal margin.
             
            addpos = [ min( addpos(1), apos(1) ), ...
                min( addpos(2), apos(2) ), ...
                max( addpos(3), sum( apos( [ 1, 3 ] ) ) - fpos(3) ), ...
                max( addpos(4), sum( apos( [ 2, 4 ] ) ) - fpos(4) ) ];
                
        end
        
        if all( strcmpi( oldactpos, 'position' ) ) & any( addpos ~= 0 )
            %Let the user know the obtained values. Useful as guidelines
            %if small adjustements are necessary.
            disp( [ 'Automatic margin correction results in: ', num2str( addpos, '%.3g ' ) ] );
        end
        
    end
    
    if any( addpos ~= 0 )
    
        %Perform modifications if necessary
        
        if all( strcmpi( oldactpos, 'position' ) )
            
            %For 'position' mode:
            %
            % - multiply addpos by a correction factor. This correction factor
            %   is calculated so that addpos really corresponds to
            %   the added length on the final figure. In other words, this
            %   scaling factor compensates the different figure scalings
            %   occuring below to modify the margins.
            %
            %This is not done for 'outerposition' mode since the 
            %scaling of the margins is impredictable in that case.
            
            %Get distances between outest axes and figure boundaries

            outestapos = [ inf, inf, 0, 0 ]; %init
            outestaposSL = outestapos; %same, but with Special treatment for outsided Legends
            obj = [ allAxesNoLegNoOL; allLegOut; allLegNoLoc ]; %combine axes and legends

            for ii = 1 : length( obj ),

                apos = get( obj( ii ), 'Position' ); %axes position
                oldoutestapos = outestapos; %store previous values
                
                %update
                outestapos = [ min( outestapos(1), apos(1) ), ...
                    min( outestapos(2), apos(2) ), ...
                    max( outestapos(3), apos(1) + apos(3) ), ... %coordinate of rhs (NOT width)
                    max( outestapos(4), apos(2) + apos(4) ) ]; %coordinate of top (NOT height)
                
                indmodif = find( oldoutestapos ~= outestapos ); %indices of updated values
                    
                if ~isempty( indmodif )
                    
                    %outestapos has been updated
                    
                    if ii > length( allAxesNoLegNoOL ) & ii <= length( [ allAxesNoLegNoOL; allLegOut ] )
                    
                        %the update is related to a legend (i.e. an outsided legend) with defined location
                        
                        %In 'position' mode and for legends with defined location, the plot related to the legend will not
                        %accommodate the space required for the legend when resizing the figure.
                        %To account for the fixed dimensions of legends, it is sufficient to
                        %include the legend extent in the desired final margin, so that
                        %corrfact (see below) is adjusted to maintain a constant space for the legend.
                        
                        %Add or remove legend width and/or height to the current margin value
                        
                        %Cases left: add legend extent and the constant distance to axes of 0.38 cm
                        outestaposSL( indmodif( indmodif == 1 ) ) = ...
                                    apos( indmodif( indmodif == 1 ) ) + apos( indmodif( indmodif == 1 ) + 2 ) + 0.38;
                                    
                        %Cases right: remove legend extent and the constant distance to axes of 0.38 cm
                        outestaposSL( indmodif( indmodif == 3 ) ) = ...
                                    apos( indmodif( indmodif == 3 ) - 2 ) - 0.38;

                        %Cases bottom: add legend extent and the constant distance to axes of 0.33 cm
                        outestaposSL( indmodif( indmodif == 2 ) ) = ...
                                    apos( indmodif( indmodif == 2 ) ) + apos( indmodif( indmodif == 2 ) + 2 ) + 0.33;
                                    
                        %Cases top: remove legend extent and the constant distance to axes of 0.33 cm
                        outestaposSL( indmodif( indmodif == 4 ) ) = ...
                                    apos( indmodif( indmodif == 4 ) - 2 ) - 0.33;
                                    
                        %NB: this 0.38 (or 0.33) value is not always very accurate. That might be a problem. If
                        %underestimated and gamma < 1, legend might be clipped. Same if overestimated
                        %and gamma > 1. The solution would be to calculate it each time, but with
                        %all the possible legend location, it's a nightmare. To solve this issue, addpos
                        %includes a 0.1 cm additional margin for legends.
                    
                    elseif ii > length( [ allAxesNoLegNoOL; allLegOut ] )
                    
                        %the update is related to a legend (i.e. an outsided legend) with UNdefined location
                        
                        %In 'position' mode for this kind of legends, the figure resizing conserves the relative
                        %position of the center of the legend.
                        %The same technique as for legends with defined locations applies, but with respect
                        %to the legend center
                        
                        %Cases left and bottom:
                        outestaposSL( indmodif( indmodif < 3 ) ) = ...
                                    apos( indmodif( indmodif < 3 ) ) + apos( indmodif( indmodif < 3 ) + 2 ) ./ 2;
                                    
                        %Cases right and top:
                        outestaposSL( indmodif( indmodif >= 3 ) ) = ...
                                    apos( indmodif( indmodif >= 3 ) - 2 ) + apos( indmodif( indmodif >= 3 ) ) ./ 2;
                    
                    else
                    
                        %Standard axes
                        outestaposSL( indmodif ) = outestapos( indmodif );
                    
                    end
                    
                end    
                    
            end
            
            %Use the margin determination including special treatment for outsided legends
            outestapos = outestaposSL;
            
            %convert to distances
            outestapos( 3 : 4 ) = fpos( 3 : 4 ) - outestapos( 3 : 4 ); %outest now containes distances from outest axes to fig bound in each directions
        
            %Correction factors and terms
            
            %Note: depending on number of zeros in addpos, the correction factors
            %and terms are calculated differently. There are 8 cases. For simplicity,
            %all the cases are calculated and the correct case is selected afterwards.
            
            %init
            figdims = fpos( [ 3, 4, 3, 4 ] ); %Order: relevant lengths for left, bottom, right, top
            addposP = addpos .* [ -1, -1, 1, 1 ]; %change signs. Easier to handle here. Understood as distance added in each direction.
            corrfact = nan( 1, 4 );
            corrterm = nan( 1, 4 );
            
            %Standard case: both figure dimensions are conserved
            
            corrfact11 = ... %Case all addpos different from 0. See justification below
                ( figdims ...
                  - outestapos( [ 3, 4, 1, 2 ] )  ...
                  + outestapos .* addposP( [ 3, 4, 1, 2 ] ) ./ addposP ) ...
                ./ ...
                ( figdims - outestapos( [ 3, 4, 1, 2 ] ) - outestapos ...
                          - addposP( [ 3, 4, 1, 2 ] ) - addposP ); 
            corrterm11 = zeros( 1, 4 );
            
            %this formulation is obtained analytically with the equations:
            % figdims(1:2) = gamma(1:2) .* ( figdims(1:2) + addposP( [ 3, 4 ] ) .*
            %                     corrfact11( [ 3, 4 ] ) + addposP(1:2) .*
            %                     corrfact11(1:2) )
            % outestapos + addposP = gamma .* ( outestapos + corrfact11 .*
            %                                  addposP )
            % gamma is the reduction factor of the extended figure size to
            % the restored (initial) figure size.
            
            %disp('check equations')
            %gamma = ( outestapos + addposP ) ...
            %         ./ ( outestapos + addposP .* corrfact11 );
            %disp( [ figdims', ( gamma .* ( figdims + addposP( [ 3, 4, 1, 2 ] ) .* ...
            %                     corrfact11( [ 3, 4, 1, 2 ] ) + addposP .* ...
            %                     corrfact11 ) )' ] );
            %disp( [ ( outestapos + addposP )', ( gamma .* ( outestapos + corrfact11 .* ...
            %                                      addposP ) )' ] );
            
            corrfact00 = ones( 1, 4 ); %Case all addpos = 0.
            corrterm00 = zeros( 1, 4 );
            
            corrfact01 = [ 1, 1, ... %Case first addpos of each pair is zero, second is not. See justification below.
                ( figdims( 3 : 4 ) - outestapos( 1 : 2 ) ) ...
                ./ ( figdims( 3 : 4 ) - outestapos( 1 : 2 ) - outestapos( 3 : 4 ) - addposP( 3 : 4 ) ) ];
            corrterm01 = ...
                [ addposP( 3 : 4 ) .* outestapos( 1 : 2 ) ...
                  ./ ( figdims( 3 : 4 ) - outestapos( 1 : 2 ) - outestapos( 3 : 4 ) - addposP( 3 : 4 ) ), 0, 0 ];
            
            corrfact10 = [ ... %Case second addpos of each pair is zero, first is not. See justification below.
                ( figdims( 1 : 2 ) - outestapos( 3 : 4 ) ) ...
                ./ ( figdims( 1 : 2 ) - outestapos( 1 : 2 ) - outestapos( 3 : 4 ) - addposP( 1 : 2 ) ), 1, 1 ];
            corrterm10 = [ 0, 0, ...
                addposP( 1 : 2 ) .* outestapos( 3 : 4 ) ...
                ./ ( figdims( 1 : 2 ) - outestapos( 1 : 2 ) - outestapos( 3 : 4 ) - addposP( 1 : 2 ) ) ];
            
            %this formulation is obtained analytically with the equations:
            % figdims(1:2) = gamma(1:2) .* ( figdims(1:2) + addposP10(1:2) .* corrfact10(1:2) + corrterm10((3:4)) )
            % outestapos + addposP10 = gamma .* ( outestapos + corrfact10 .* addposP10 + corrterm10 )
            % gamma is the reduction factor of the extended figure size to
            % the restored (initial) figure size.
            
            %Identify case
            
            blnaddpos1 = ( addpos ~= 0 ); %true if addpos is not zero
            
            for ii = 1 : 2
                
                %ii = 1: left and right 
                %ii = 2: bottom and top
                
                if all( blnaddpos1( [ ii, ii + 2 ] ) )
                
                    %both non zero
                    corrfact( [ ii, ii + 2 ] ) = corrfact11( [ ii, ii + 2 ] );
                    corrterm( [ ii, ii + 2 ] ) = corrterm11( [ ii, ii + 2 ] );
                    
                elseif blnaddpos1( ii )
                
                    %first one non zero and second one zero (by deduction)
                    corrfact( [ ii, ii + 2 ] ) = corrfact10( [ ii, ii + 2 ] );
                    corrterm( [ ii, ii + 2 ] ) = corrterm10( [ ii, ii + 2 ] );
                    
                elseif blnaddpos1( ii + 2 )
                    
                    %first one zero and second one non zero (by deduction)
                    corrfact( [ ii, ii + 2 ] ) = corrfact01( [ ii, ii + 2 ] );
                    corrterm( [ ii, ii + 2 ] ) = corrterm01( [ ii, ii + 2 ] );
                
                else
                    
                    %both zero
                    corrfact( [ ii, ii + 2 ] ) = corrfact00( [ ii, ii + 2 ] );
                    corrterm( [ ii, ii + 2 ] ) = corrterm00( [ ii, ii + 2 ] );
                                    
                end    
                
            end
             
            %If tight mode with conserved scaling, only
            %one of the figure dimension is conserved.
            %In that case, the correction factors of the modified
            %dimension follow the 2nd equations above and the first
            %equations are replaced by the condition of constant scale
            %factor gamma between dimension x and y.
            
            if ~isempty( tight ) & ~strcmpi( tight, 'xy' )
                
                if strcmpi( tight, 'x' )
                
                    %Keep figure dimension along x
                    %Modif corrfact along y to satisfy constant scaling in both dimensions
                    
                    %gamma given by scaling along x dimension
                    gamma = figdims(1) ./ ( figdims(1) ...
                                          + addposP(3) .* corrfact(3) ...
                                          + addposP(1) .* corrfact(1) + corrterm(1) + corrterm(3) );
                    
                    %store indices of values to be modified
                    indaddpos1 = find( addpos ~= 0 & [ false, true, false, true ] ); %ind of non zero addpos amongst [ 2, 4 ]
                    indaddpos0 = find( addpos == 0 & [ false, true, false, true ] ); %ind of zero addpos amongst [ 2, 4 ]
                    
                else
                    
                    %Keep figure dimension along y
                    %Modif corrfact along x to satisfy constant scaling in both dimensions
                    
                    %gamma given by scaling along y dimension
                    gamma = figdims(2) ./ ( figdims(2) ...
                                          + addposP(4) .* corrfact(4) ...
                                          + addposP(2) .* corrfact(2) + corrterm(2) + corrterm(4) );
                    
                    %store indices of values to be modified
                    indaddpos1 = find( addpos ~= 0 & [ true, false, true, false ] ); %ind of non zero addpos amongst [ 1, 3 ]
                    indaddpos0 = find( addpos == 0 & [ true, false, true, false ] ); %ind of zero addpos amongst [ 1, 3 ]
                    
                end
                
                %modif corrfact and corrterm accordingly
                corrfact( indaddpos1 ) = ( ( 1 - gamma ) * outestapos( indaddpos1 ) + addposP( indaddpos1 ) ) ...
                                          ./ ( gamma * addposP( indaddpos1 ) );
                corrfact( indaddpos0 ) = 1;
                corrterm( indaddpos1 ) = 0;
                corrterm( indaddpos0 ) = ( 1 - gamma ) * outestapos( indaddpos0 ) ./ gamma;                      
                                      
                %disp( 'Check equations' )
                %disp( gamma )
                %disp( ( ( outestapos + addposP ) ...
                %     ./ ( outestapos + addposP .* corrfact ) )' ); %all gammas must be the same
                %disp( [ ( outestapos + addposP )', ( gamma .* ( outestapos + corrfact .* ...
                %                                  addposP ) )' ] );
                    
            end            
            
            %express corrterm in same sense as addpos (instead of same sense as addposP)
            corrterm = corrterm .* [ -1, -1, 1, 1 ];
            
            %corr addpos
            addpos = corrfact .* addpos + corrterm;
            
        end
        
        if length( marginfactor ) == 1
                    
            addpos = addpos .* marginfactor; %increase the additional margins.
            
        end
        
        %shift all axes by exceeding distance on left and bottom
        
        %Uniform behaviour when re-setting axes position:    
        %Use 'position' mode to make sure that axes behave as expected.
        %Anyway, for unknown reasons, using set( axes,'position', ... ) sets
        %the activeposition to 'position'. Just make it explicit here.
        shiftedobj = [ allAxesNoLeg; allLegNoLoc ]; %combine all axes with the legends that have no relative positionning. The other legends are positionned automatically by Matlab.
        set( shiftedobj, { 'ActivePositionProperty' }, { 'Position' } );
        
        for ii = 1 : length( shiftedobj ),
        
            apos = get( shiftedobj( ii ), 'position' );

            apos( 1 : 2 ) = apos( 1 : 2 ) - addpos( 1 : 2 ); %NB: addpos(1:2) is negative

            set( shiftedobj( ii ), 'position', apos );
        
        end
        
        %correct figure position
        %just work on width and height for the figure frame
        newpos = [ fpos( 1 : 2 ), ...
            fpos(3) - addpos(1) + addpos(3), ...
            fpos(4) - addpos(2) + addpos(4) ]; %NB: addpos(1:2) is negative
        set( H, 'Position', newpos ); %to have all the labels displayed
        
        drawnow %need to be called after resizing figure window
        
        %Adapt axes sizes while restoring figure position
        
        set( [ allAxesNoLeg; allLegTarget ], 'Units', 'Normalized' );
        
        %restore active position before resizing the figure. Legends should always be in 'position' mode since they have no labels.
        set( allAxesNoLeg, { 'ActivePositionProperty' }, oldactpos );
        
        if ~isempty( tight ) & strcmpi( tight, 'x' )
            
            %Tight, keep figure dimension along x, keep scaling
            scale = newpos(4) / newpos(3); %height over width of intermediate figure position
            fpos(4) = scale * fpos(3); %modify height to conserve scale
            
        elseif ~isempty( tight ) & strcmpi( tight, 'y' )
            
            %Tight, keep figure dimension along y, keep scaling
            scale = newpos(4) / newpos(3); %height over width of intermediate figure position
            fpos(3) = fpos(4) / scale; %modify height to conserve scale
            
        else
            
            %Not tight or 'xy' mode
            % -> keep fpos untouched
            
        end
        
        set( H, 'Position', fpos );
        drawnow %need to be called after resizing figure window
        
        %Check
        newfpos = get( H, 'Position' );
        if any( abs( fpos( 3 : 4 ) - newfpos( 3 : 4 ) ) > 0.1 ) %1mm tolerance
            disp( [ '!!! The new figure is too large or too high to fit on the screen.', ...
                    ' Arbitrary resizing will occur. Please reduce the target width or height.' ] );
        end
        
    end %test on addpos ~= 0
    
    %restore units
    set( allAxesNoLeg, { 'Units' }, oldaxesunits );
    set( allLegTarget, { 'Units' }, oldlegunits  );
    set( H, 'Units', oldfigunits );
        
    if all( strcmpi( oldactpos, 'outerposition' ) ) ...
        & ~isempty( tight ) & length( marginfactor ) == 1 & ~blnInnerCall
        
        %2nd run to reduce extra margins due to outerposition mode
        %(necessary since no correction factor can be determined in that case)
        
        marginfactor = 1; %marginfactor not re-applied
        Local_AdaptAxes_7x( H, allAxesNoLeg, allLeg, marginfactor, tight, blnLockAxes, true );
    end
       
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function Local_MatchColorBars( targAxes );
    %targAxes: cb and their related axes
    
    %harmonize colorbars and axes
    allColorbars = targAxes(find(strcmpi(get(targAxes,'Tag'),'Colorbar')));
        
    %store axes units and reset
    oldunits = get(targAxes,'Units');
    set(targAxes,'Units','centimeters'); %to avoid automatic resizing
    
    for ii = 1:length(allColorbars),
        %find related plot
        tmp = get(allColorbars(ii),'UserData');
        relatedplot = tmp.PlotHandle;

        if ~isempty(get(relatedplot,'ZTickLabel')),
            %3D plot
            %don't do anything
            continue
        end

        cbpos = get(allColorbars(ii),'Position');
        cbxlab = get(allColorbars(ii),'Xlabel');
        cbxlabpos = get(cbxlab,'Position');
        cbylab = get(allColorbars(ii),'Ylabel');
        cbylabpos = get(cbylab,'Position');
        plpos = get(relatedplot,'Position');
        plxlab = get(relatedplot,'Xlabel');
        plxlabpos = get(plxlab,'Position');
        plylab = get(relatedplot,'Ylabel');
        plylabpos = get(plylab,'Position');

        if cbpos(3) > cbpos(4),
            %horizontal bar, adjust left and width
            pos = [max(cbpos(1),plpos(1)),min(cbpos(1)+cbpos(3),plpos(1)+plpos(3))]; %left,right
            pos(2) = pos(2)-pos(1); %left,width

            %set axes position
            set(allColorbars(ii),'Position',[pos(1),cbpos(2),pos(2),cbpos(3)]);
            set(relatedplot,'Position',[pos(1),plpos(2),pos(2),plpos(3)]);

            %set labels (centered)
            set(cbxlab,'Position',[pos(2)/2,cbxlabpos(2:3)]);
            set(plxlab,'Position',[pos(2)/2,plxlabpos(2:3)]);
        else
            %vertical bar, adjust bottom and height
            pos = [max(cbpos(2),plpos(2)),min(cbpos(2)+cbpos(4),plpos(2)+plpos(4))]; %bottom,top
            pos(2) = pos(2)-pos(1); %bottom,height

            %set axes position
            set(allColorbars(ii),'Position',[cbpos(1),pos(1),cbpos(3),pos(2)]);
            set(relatedplot,'Position',[plpos(1),pos(1),plpos(3),pos(2)]);

            %set labels (centered)
            set(cbylab,'Position',[cbylabpos(1),pos(2)/2,cbylabpos(3)]);
            set(plylab,'Position',[plylabpos(1),pos(2)/2,plylabpos(3)]);
        end
    end %loop on colorbars
    
     %restore axes units
    if ~iscell(oldunits), oldunits = {oldunits}; end
    set(targAxes,{'Units'},oldunits);
        
return




